# face_api.py
import os, time
import cv2 as cv
import numpy as np
import threading
from flask import Flask, request, jsonify
from flask_cors import CORS

# ---------------------- 共享全局变量（需与main.py保持一致，通过外部赋值初始化） ----------------------
# 从main.py导入或接收赋值：确保与原系统状态同步
shared_vars = {
    "is_running": True,       # 控制API线程运行（同步main.py的is_running）
    "user_dict": [],          # 已注册用户名列表（同步main.py的user_dict）
    "recognizer": None,       # 人脸识别器（复用main.py的训练模型）
    "face_cas": None,         # 人脸检测器（复用main.py的检测器）
    "wb": None,               # Excel工作簿（复用main.py的考勤表）
    "ws": None,               # Excel工作表（复用main.py的工作表）
    "begin_row": 0,           # Excel起始行（复用main.py的begin_row）
    "today": ""               # 当前日期（复用main.py的today）
}

# API专用资源（独立于main.py，避免资源冲突）
api_camera = None  # API专用摄像头
api_lock = threading.Lock()  # API线程锁（保护摄像头/模型操作）
api_app = Flask(__name__)
CORS(api_app)  # 允许跨域（外部系统调用需开启）


# ---------------------- API工具函数 ----------------------
def init_api_camera():
    """初始化API专用摄像头（避免与main.py的摄像头冲突）"""
    global api_camera
    if api_camera is None or not api_camera.isOpened():
        api_camera = cv.VideoCapture(0)
        if not api_camera.isOpened():
            raise Exception("API摄像头初始化失败：无法打开摄像头设备")
    return api_camera


def release_api_camera():
    """释放API专用摄像头"""
    global api_camera
    if api_camera is not None and api_camera.isOpened():
        api_camera.release()
    api_camera = None


def api_face_recognize(username):
    """API核心识别逻辑：验证用户名与实时人脸是否匹配"""
    global shared_vars, api_lock
    api_lock.acquire()  # 加锁：确保线程安全
    try:
        # 1. 检查必要资源是否已从main.py同步
        required_vars = ["user_dict", "recognizer", "face_cas", "wb", "ws", "begin_row", "today"]
        for var in required_vars:
            if shared_vars[var] is None or (isinstance(shared_vars[var], list) and len(shared_vars[var]) == 0):
                return {"success": False, "reason": f"系统资源未初始化（缺失{var}）"}

        # 2. 基础校验
        if username not in shared_vars["user_dict"]:
            return {"success": False, "reason": f"用户名「{username}」未注册，请先在系统中登记"}
        if not os.path.exists("trainner.yml"):
            return {"success": False, "reason": "未找到人脸训练模型，请先注册人脸"}

        target_id = shared_vars["user_dict"].index(username)  # 目标用户ID（与main.py一致）
        shared_vars["recognizer"].read("trainner.yml")  # 加载训练模型
        if shared_vars["recognizer"].empty():
            return {"success": False, "reason": "人脸模型加载失败，可能模型文件损坏"}

        # 3. 启动摄像头识别
        file_path = "api_result.txt"
        if os.path.exists(file_path):
            os.remove(file_path)
        shared_vars["message_queue"].clear_queue_from_gui()
        shared_vars["message_queue"].send_to_gui({
            'type': 'press_button',
            'data': 'press button'
        })
        times = 100
        while times > 0:
            message = shared_vars["message_queue"].receive_from_gui(timeout=1)
            if message:
                msg_type = message.get('type')
                data = message.get('data')
                if msg_type == 'scan_result':
                    xman = data
                    if xman == username:
                        return {"success": True, "reason": f"人脸识别成功，已为「{username}」记录考勤"}
                    else:
                        return {"success": False, "reason": f"识别 wrong man failed. "}
                elif msg_type == 'scan_failed':
                    return {"success": False, "reason": f"识别 failed from GUI. "}
                else:
                    print(f"receive from gui {msg_type}")
            time.sleep(1)
            times = times - 1
        return {"success": False, "reason": f"识别 failed. "}
        # 4. 处理识别结果
    except Exception as e:
        return {"success": False, "reason": f"识别过程异常：{str(e)}"}
    finally:
        release_api_camera()  # 释放摄像头
        api_lock.release()    # 解锁


# ---------------------- API接口定义 ----------------------
@api_app.route("/verify", methods=["POST"])
def face_verify():
    """
    人脸识别验证接口（供外部系统调用，如LDAP代理）
    请求参数：{"username": "待验证用户名"}
    返回结果：{"success": bool, "reason": str}
    """
    if not shared_vars["is_running"]:
        return jsonify({"success": False, "reason": "刷脸系统已关闭，无法进行识别"})

    # 解析请求参数
    try:
        data = request.get_json()
    except Exception:
        return jsonify({"success": False, "reason": "请求格式错误，请使用JSON格式传递参数"})
    
    if not data or "username" not in data:
        return jsonify({"success": False, "reason": "请求参数缺失，需包含「username」字段"})
    
    username = data["username"].strip()
    if not username:
        return jsonify({"success": False, "reason": "「username」不能为空，请输入有效的用户名"})

    # 调用识别逻辑并返回结果
    result = api_face_recognize(username)
    print(f"result: {result}")
    return jsonify(result)


# ---------------------- API服务启动函数（供main.py调用） ----------------------
def start_api_server(host="0.0.0.0", port=5000):
    """
    启动API服务（需在独立线程中运行，避免阻塞main.py的GUI）
    :param host: 服务绑定IP（0.0.0.0允许外部访问）
    :param port: 服务端口（默认5000）
    """
    global api_app
    print(f"API服务启动中... 接口地址：http://{host}:{port}/api/face/verify")
    # use_reloader=False：禁用Flask自动重载（避免启动多个线程），debug=False：生产环境关闭调试
    api_app.run(host=host, port=port, debug=False, use_reloader=False)


# ---------------------- API服务停止函数（供main.py调用） ----------------------
def stop_api_server():
    """停止API服务，释放资源"""
    shared_vars["is_running"] = False
    release_api_camera()
    print("API服务已停止，资源已释放")

